%module(package="kuai") kuaiext

%{
#include "typedef.h"
#include "xyz.h"
#include "const.h"
#include "pbc.h"

using namespace kuai;
%}


%include "typedef.h"
namespace kuai {	
    extern const int SIZE_OF_REAL_NUMBER;
    extern const int SIZE_OF_ATOM_INDEX; 
}

%include "xyz.h"
namespace kuai {
    %extend XYZ {
        RealNumber __abs__() const {
            return $self->abs();	
        }

        %pythoncode %{
            def __repr__(self):
                return '(' + str(self.x) + ', ' + str(self.y) + ', ' + str(self.z) + ')'
        %}
    }
}

%include "pbc.h"
namespace kuai {

    %ignore PBC::update(XYZ&) const;
    %ignore PBC::update(RealNumber v[]) const;
    %ignore PBC::shift(const XYZ& v) const;
    %extend PBC {
        PyObject* shift(const XYZ& v) const {
            int s[3];
            $self->shift(v, s);
            PyObject* result = PyTuple_New(3);
            PyTuple_SetItem(result, 0, PyInt_FromLong(s[0]));
            PyTuple_SetItem(result, 1, PyInt_FromLong(s[1]));
            PyTuple_SetItem(result, 2, PyInt_FromLong(s[2]));
            return result;    
        }
        %pythoncode %{
            def __repr__(self):
                from math import degrees
                result = 'PBC: %10.4f %10.4f %10.4f %6.2f %6.2f %6.2f' % \
                            (self.a(), self.b(), self.c(), 
                            degrees(self.alpha()), degrees(self.beta()), degrees(self.gamma()), )
                return result
        %}
    }
}

namespace kuai {

    %apply (RealNumber IN_ARRAY1[ANY]) {(RealNumber x[])}
    %apply (RealNumber IN_ARRAY1[ANY]) {(RealNumber k[])}
    %apply (AtomIndex* IN_ARRAY1, int DIM1) {(AtomIndex* items, int number)}
    %apply (RealNumber* INPLACE_ARRAY1) {(RealNumber result[])}
}


